package eolympics;

import java.util.ArrayList;
import java.util.List;

import minigames.IMiniGame;

import jexxus.common.Connection;
import jexxus.common.Delivery;
import data.GameState;
import data.IPlayerReadOnly;
import data.Player;

public class Communicator
{
    public enum MessageType
    {
        GAME_STATE("<gs>"),
        PLAYER_NAME("<pn>"),
        PLAYER_LIST("<pl>"),
        PLAYER_READY("<pr>"),
        MINI_GAME_CHOSEN("<mc>");

        public final static int PREFIX_LENGTH = 4;
        private String          mPrefix;

        MessageType(final String pPrefix)
        {
            mPrefix = pPrefix;
        }

        String getPrefix()
        {
            return mPrefix;
        }

        public static MessageType getMessageType( final String pPrefix )
        {
            for( MessageType currentMessageType : MessageType.values() )
            {
                if( currentMessageType.getPrefix().equals(pPrefix) )
                {
                    return currentMessageType;
                }
            }

            throw new RuntimeException("MessageType not found with prefix: " + pPrefix);
        }
    }

    public static void sendChosenMiniGameToClient( final Connection pConnection, final IMiniGame miniGame )
    {
        String chosenMinigameMessage = MessageType.MINI_GAME_CHOSEN.getPrefix() + miniGame.getName();
        pConnection.send(chosenMinigameMessage.getBytes(), Delivery.TCP);
    }

    public static void sendPlayerIsReadyToServer( final Connection pConnection )
    {
        String playerReadyMessage = MessageType.PLAYER_READY.getPrefix();
        pConnection.send(playerReadyMessage.getBytes(), Delivery.TCP);
    }

    public static void sendGameStateToClient( final GameState pGameState, final Connection pClient )
    {
        String gameStateMessage = MessageType.GAME_STATE.getPrefix() + pGameState.name();
        pClient.send(gameStateMessage.getBytes(), Delivery.TCP);
    }

    public static void sendPlayerNameToServer( final String playerName, final Connection pConnection )
    {
        String playerNameMessage = MessageType.PLAYER_NAME.getPrefix() + playerName;
        pConnection.send(playerNameMessage.getBytes(), Delivery.TCP);
    }

    public static void sendPlayerListToClient( final List<IPlayerReadOnly> pPlayerList, final Connection pClient )
    {
        StringBuffer players = new StringBuffer();

        for( IPlayerReadOnly currentPlayer : pPlayerList )
        {
            players.append("<");
            players.append(currentPlayer.getName());
            players.append(">");
            players.append(currentPlayer.getIp());
            players.append(">");
            players.append(currentPlayer.isReady());
        }

        String gameStateMessage = MessageType.PLAYER_LIST.getPrefix() + players.toString();

        pClient.send(gameStateMessage.getBytes(), Delivery.TCP);
    }

    public static String getPlayerName( final String pMessage )
    {
        String playerName = pMessage.substring(MessageType.PLAYER_NAME.getPrefix().length());

        return playerName;
    }

    public static IMiniGame getChosenMiniGame( final String pMessage, List<IMiniGame> pMiniGames )
    {
        String miniGameName = pMessage.substring(MessageType.PLAYER_NAME.getPrefix().length());

        for( IMiniGame minigame : pMiniGames )
        {
            if( minigame.getName().equals(miniGameName) )
            {
                return minigame;
            }
        }

        throw new RuntimeException("no mini game found with that name: " + miniGameName);
    }

    public static GameState getGameState( final String pMessage )
    {
        GameState gameState = GameState.valueOf(pMessage.substring(MessageType.PREFIX_LENGTH));

        return gameState;
    }

    public static List<Player> getPlayerList( final String pMessage )
    {
        String players = pMessage.substring(MessageType.PREFIX_LENGTH);

        List<Player> playerList = new ArrayList<>();

        String[] playersArray = players.split("<");

        for( String aPlayer : playersArray )
        {
            String currentPlayer = aPlayer.trim();
            if( currentPlayer.length() == 0 )
            {
                continue;
            }

            String[] playerParts = currentPlayer.split(">");

            Player player = new Player();
            player.setName(playerParts[0]);
            player.setIp(playerParts[1]);
            player.setReady(Boolean.valueOf(playerParts[2]));
            playerList.add(player);
        }

        return playerList;
    }

    public static MessageType getMessageType( final String pMessage )
    {
        String messageType = pMessage.substring(0, MessageType.PREFIX_LENGTH);

        return MessageType.getMessageType(messageType);
    }
}
